package TCP;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Author YuanYuan
 * @Date 2022/10/14
 * @Time 19:21
 */

public class TcpEchoSever {
    //代码中会设计多个 socket 对象,使用不同的名字来区分,使用listenSeverSocket来进行监听
    public ServerSocket listenSeverSocket = null;

    public TcpEchoSever(int port) throws IOException {
        listenSeverSocket = new ServerSocket(port);
    }

    public void start() throws IOException {
        System.out.println("服务器启动!");
        ExecutorService service = Executors.newCachedThreadPool();
        while (true) {
            //1. 先调用 appect 来 接受客户端的连接
            Socket clientSocket = listenSeverSocket.accept();
            //2.处理这个连接
            //使用线程池保证可以同时处理多个客户端
            service.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        processConnect(clientSocket);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });
        }

//        while (true) {
//            Socket clientSocket = listenSeverSocket.accept();
//            Thread thread = new Thread(()-> {
//                processConnect(clientSocket);
//            });
//            thread.start();
//        }


    }

    public void processConnect(Socket clientSocket) throws IOException {
        System.out.println("客户端上线!");
        //接下来处理客户端的请求
        //拿到输入流输出流对象
        try(InputStream inputStream = clientSocket.getInputStream();
            OutputStream outputStream = clientSocket.getOutputStream()) {
            //客户端可能会发多条数据
            while(true) {
                //1.读取请求并解析
                Scanner scanner = new Scanner(inputStream);
                if(!scanner.hasNext()) {
                    //读完了,连接断开
                    System.out.printf("客户端读完了:[%s:%d]",clientSocket.getInetAddress().toString(),clientSocket.getPort());
                    break;
                }
                //读取到请求
                String request = scanner.next();
                //2. 根据请求计算响应
                String response = process(request);
                //3.把响应写回给客户端
                PrintWriter printWriter = new PrintWriter(outputStream);
                printWriter.println(response);
                //刷新缓冲区确保数据确实是通过网卡发送出去了
                printWriter.flush();

                //打印日志
                System.out.printf("[客户端ip地址: %s 客户端端口号: %d],请求: %s , 回应: %s \n", clientSocket.getInetAddress().toString(),
                        clientSocket.getPort(),request,response);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            clientSocket.close();
        }
    }
    public String process(String requst) {
        return requst;
    }

    public static void main(String[] args) throws IOException {
        TcpEchoSever tcpEchoSever = new TcpEchoSever(9000);
        tcpEchoSever.start();
    }
}
